package cn.blogsx.reflect;

import cn.blogsx.domain.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.stream.Stream;

/**
 * 反射的功能：
 *    1.获取成员变量们
 *          * Field[] getFields() 获取所有public修饰的成员变量
 *          * Field getField(String name) 获取指定名称的public修饰的成员变量
 *
 *          * Field[] getDeclaredFields() //获取所有的成员变量
 *          * Field getField(String name)
 *    2.获取构造方法们
 *          * Constructor<?>[] getConstructors()
 *          * Constructor<T> getConstructor(Class<?>... parameterTypes)
 *
 *          * Constructor<?>[] getDeclaredConstructors()
 *          * Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
 *
 *    3.获取成员方法们
 *          * Method[] getMethods()
 *          * Method getMethod(String name, Class<?>... parameterTypes)
 *          * Method[] getDeclaredMethods()

 *    4.获取类名
 *          * String getName();
 *
 * Field:成员变量
 *  * 操作：
 *      1、设置值
 *           void set(Object obj, Object value)
 *      2、获取值
 *           Object get(Object obj)
 *      3、忽略访问修饰符的安全检查
 *          字段名setAccessible(true); //暴力反射
 *
 * constructor构造方法
 *      * 创建对象： T newInstance(Object... initargs)
 *       如果使用空参数构造方法创建对象，操作可以简化：Class对象里边的 newInstance
 *
 * Method:执行方法
 * 执行方法： Object invoke(Object obj, Object... args)
 * 获取方法名：
 *          String getName();
 */
public class Demo04ReflectMemberFunction {
    public static void main(String[] args) throws Exception {
        Class pClass = Person.class;
        /**
         *    3.获取成员方法们
         *          * Method[] getMethods()
         *          * Method getMethod(String name, Class<?>... parameterTypes)
         *          * Method[] getDeclaredMethods()
         */

        //获取指定名称的方法
        Method eatMethod = pClass.getMethod("eat");
        Person p = new Person();
        //执行无参成员方法
        eatMethod.invoke(p);

        //获取指定名称和参数的方法
        Method eatFoodMethod = pClass.getMethod("eat",String.class);
        //执行有参方法
        eatFoodMethod.invoke(p,"苹果");

        //获取所有public 选修饰的方法,也支持setAccessible(true);暴力反射获取所有的方法
        Method[] methods = pClass.getMethods();
        //遍历methods
        Stream.of(methods).map((Method s)->{
            return "方法名"+s.getName()+" " +s;
        }).forEach(System.out::println);

    }
}
